
import { AIConfig } from "../AIConfig";
import { AICore } from "../AICore";
import { AIPanel } from "../AIPanel";
import { getAudio, uploadFile } from "../Imagen";
import { CustomButtonsField } from "../field/CustomButtonsField";
import { TextAreaField } from "../field/TextAreaField";
import { AITask } from "./AITask";

class GenAudioData{
    desc='用吉他演奏的欢快的乡村歌曲';
    temperature=1;
    duration=10;
    mode=1;
    assetName='aigen.mp3'
    errorMsg:string;
    refMusic:string;
    showOK=true;
    showCancel=true;
}

/** 音乐生成是一个单步任务 */

export class AITaskGenAudioNode extends AITask{
    data = new GenAudioData();
    static EditObjName='音乐'
    resultAssetName:string=null;


    private async onClickResult(){
        let asset = await Editor.assetDb.getAsset(this.resultAssetName);
        Editor.scene?.setSelection([asset], "asset");
    }

    private onModeChange(event:Event){
        let value = parseInt((event.target as HTMLInputElement).value)??1;
        if(isNaN(value)) value=1;
        this.data.mode = value;
    }

    private async onRefFileChange(event:Event){
        var file = (event.target as any).files[0]; // 获取选中的文件  
        var fileName = file.name; // 获取文件名  
        let remotefile = await uploadFile(AIConfig.MusicGenUploadUrl,file);
        console.log('sv file url ', remotefile.fileid)
    }    

    async showUI(){
        let me = this;
        let msg:any = {
            name: "生成音乐",
            properties: [
                {
                    label:'描述:',
                    name: "desc",
                    type: "string",
                    default:this.data.desc,
                    inspector: TextAreaField,
                    onChange: (key: string, val: any, data: any) => {
                        this.data.desc = val;
                    }
                },
                {
                    label:'时间(秒):',
                    name: "duration",
                    type: 'number',
                    default:this.data.duration,
                    onChange: (key: string, val: number, data: any) => {
                        if(val>60){
                            val=60;
                            data[key]=60;
                        }
                        this.data.duration=val;
                    }
                },
                {
                    name: "CustomButton",
                    inspector: CustomButtonsField,
                    onClick:(e:gui.Event)=>{
                        me.generateMusic(true);
                    }
                },
            ]
        }
        this.msgid = await AIPanel.ins.addMsg(msg,-1,{data:this.data})        
    }

    async generateMusic(randname=true){
        let data = this.data;
        if(randname){
            data.assetName='music_'+Date.now()+'.mp3';
        }

        //let data = {  name:, temperature:1.0, duration:10,mode:0 };
        let wmsg = await AIPanel.ins.startWaitMsg('正在生成音乐');
        let buff = await getAudio(
            {
                name:this.data.desc,
                temperature:data.temperature,
                duration:data.duration,
                refMusic:data.refMusic,
                mode:data.mode
            }
        ) as ArrayBuffer;

        if(!buff){
            AIPanel.ins.removeMsg(wmsg);
            return null;
        }
        if(this._isCancel){
            AIPanel.ins.removeMsg(wmsg);
            return null;
        }

        let ideAgent = AICore.inst.ideAgent;
        let file = await ideAgent.saveBuffToTmp(Buffer.from(buff), 'mp3');
        let assetname = (data.assetName||'aigen.mp3').toLowerCase();
        if(!assetname.endsWith('.mp3')){
            assetname+='.mp3';
        }

        let asset = await ideAgent.crateAIAssetFromFile(file, 'music', assetname);
        this.genAsset = asset;
        AIPanel.ins.removeMsg(wmsg);
        this.resultAssetName = asset.fileName;
        // 预览添加到聊天界面
        AIPanel.ins.addSound(file);
        //资源保存ai信息
        ideAgent.setAIInfo(asset.id,data,true);
        return asset;
    }

    /**
     * 任务创建后会立即执行
     * 所以这里会包含更新界面的流程
     */
    async execute(){
        let data = this.data;
        data.assetName='music_'+Date.now()+'.mp3';
        this.showUI();
        //如果cancel的话，就返回最后的结果？
        await this.waitIt();
    }
}
